package cn.ug.activity.web.controller;

import static cn.ug.util.ConstantUtil.NORMAL_DATE_FORMAT;

import cn.ug.activity.bean.ChannelBean;
import cn.ug.activity.bean.GiveOutAverageValueBean;
import cn.ug.activity.bean.GiveOutBean;
import cn.ug.activity.bean.GiveOutFutureValueBean;
import cn.ug.activity.service.CouponMemberService;
import cn.ug.activity.web.utils.ExcelUtil;
import cn.ug.bean.base.DataTable;
import cn.ug.bean.base.Page;
import cn.ug.bean.base.SerializeObject;
import cn.ug.bean.type.ResultType;
import cn.ug.config.AplicationResourceProperties;
import cn.ug.core.SerializeObjectError;
import cn.ug.util.PaginationUtil;
import cn.ug.util.UF;
import cn.ug.web.controller.BaseController;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;

@RestController
@RequestMapping("data")
public class DataController extends BaseController {
    @Autowired
    private CouponMemberService couponMemberService;
    @Autowired
    protected AplicationResourceProperties properties;

    @GetMapping(value = "/total/list")
    public SerializeObject<DataTable<GiveOutBean>> list(@RequestHeader String accessToken, Page page, Integer timeType, String startDate, String endDate, String[] channelIds) {
        timeType = timeType == null ? 1 : timeType;
        startDate = UF.toString(startDate);
        endDate = UF.toString(endDate);
        if (StringUtils.isBlank(startDate) && StringUtils.isBlank(endDate)) {
            SimpleDateFormat dateFormat = new SimpleDateFormat(NORMAL_DATE_FORMAT);
            if (timeType == 1) {
                Calendar calendar = Calendar.getInstance();
                endDate = dateFormat.format(calendar.getTime());
                calendar.add(Calendar.DAY_OF_YEAR, -6);
                startDate = dateFormat.format(calendar.getTime());
            } else if (timeType == 2) {
                Calendar calendar = Calendar.getInstance();
                endDate = dateFormat.format(calendar.getTime());
                calendar.add(Calendar.MONTH, -1);
                calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMinimum(Calendar.DAY_OF_MONTH));
                startDate = dateFormat.format(calendar.getTime());
            } else if (timeType == 3) {
                Calendar calendar = Calendar.getInstance();
                endDate = dateFormat.format(calendar.getTime());
                int week = calendar.get(Calendar.DAY_OF_WEEK);
                int days = 42;
                week--;
                if (week == 0) {
                    week = 7;
                }
                week--;
                days += week;
                calendar.add(Calendar.DAY_OF_YEAR, -days);
                startDate = dateFormat.format(calendar.getTime());
            }
        }
        if (StringUtils.isBlank(startDate) || StringUtils.isBlank(endDate)) {
            return new SerializeObjectError("22000025");
        }
        List<String> channels = null;
        if (channelIds != null && channelIds.length > 0) {
            channels = new ArrayList<String>();
            for (String channelId : channelIds) {
                channels.add(channelId);
            }
        }
        List<GiveOutBean> data = couponMemberService.listGrantStatistics(timeType,startDate, endDate, channels);
        if (data != null && data.size() > 0) {
            page.setTotal(data.size());
            if (page.getPageSize() > 0) {
                data = data.stream().skip((PaginationUtil.getPage(page.getPageNum())-1) * page.getPageSize()).limit(page.getPageSize()).collect(Collectors.toList());
            }
            return new SerializeObject<>(ResultType.NORMAL,startDate+":"+endDate, new DataTable<GiveOutBean>(page.getPageNum(), page.getPageSize(), page.getTotal(), data));
        } else {
            return new SerializeObject<>(ResultType.NORMAL, startDate+":"+endDate, new DataTable<GiveOutBean>(page.getPageNum(), page.getPageSize(), page.getTotal(), new ArrayList<GiveOutBean>()));
        }
    }

    @GetMapping(value = "/avg/list")
    public SerializeObject<DataTable<GiveOutAverageValueBean>> avgList(@RequestHeader String accessToken, Page page, Integer type, Integer timeType, String startDate, String endDate, String[] channelIds) {
        timeType = timeType == null ? 1 : timeType;
        type = type == null ? 1 : type;
        startDate = UF.toString(startDate);
        endDate = UF.toString(endDate);
        if (StringUtils.isBlank(startDate) && StringUtils.isBlank(endDate)) {
            SimpleDateFormat dateFormat = new SimpleDateFormat(NORMAL_DATE_FORMAT);
            if (timeType == 1) {
                Calendar calendar = Calendar.getInstance();
                endDate = dateFormat.format(calendar.getTime());
                calendar.add(Calendar.DAY_OF_YEAR, -6);
                startDate = dateFormat.format(calendar.getTime());
            } else if (timeType == 2) {
                Calendar calendar = Calendar.getInstance();
                endDate = dateFormat.format(calendar.getTime());
                calendar.add(Calendar.MONTH, -1);
                calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMinimum(Calendar.DAY_OF_MONTH));
                startDate = dateFormat.format(calendar.getTime());
            } else if (timeType == 3) {
                Calendar calendar = Calendar.getInstance();
                endDate = dateFormat.format(calendar.getTime());
                int week = calendar.get(Calendar.DAY_OF_WEEK);
                int days = 42;
                week--;
                if (week == 0) {
                    week = 7;
                }
                week--;
                days += week;
                calendar.add(Calendar.DAY_OF_YEAR, -days);
                startDate = dateFormat.format(calendar.getTime());
            }
        }
        if (StringUtils.isBlank(startDate) || StringUtils.isBlank(endDate)) {
            return new SerializeObjectError("22000025");
        }
        List<String> channels = null;
        if (channelIds != null && channelIds.length > 0) {
            channels = new ArrayList<String>();
            for (String channelId : channelIds) {
                channels.add(channelId);
            }
        }
        List<GiveOutAverageValueBean> data = couponMemberService.listAvgValueStatistics(type, timeType,startDate, endDate, channels);
        if (data != null && data.size() > 0) {
            page.setTotal(data.size());
            if (page.getPageSize() > 0) {
                data = data.stream().skip((PaginationUtil.getPage(page.getPageNum())-1) * page.getPageSize()).limit(page.getPageSize()).collect(Collectors.toList());
            }
            return new SerializeObject<>(ResultType.NORMAL, startDate+":"+endDate, new DataTable<GiveOutAverageValueBean>(page.getPageNum(), page.getPageSize(), page.getTotal(), data));
        } else {
            return new SerializeObject<>(ResultType.NORMAL, startDate+":"+endDate, new DataTable<GiveOutAverageValueBean>(page.getPageNum(), page.getPageSize(), page.getTotal(), new ArrayList<GiveOutAverageValueBean>()));
        }
    }

    @GetMapping(value = "/future/list")
    public SerializeObject<DataTable<GiveOutFutureValueBean>> futureFutrueList(@RequestHeader String accessToken, Page page, String startDate, String endDate, String[] channelIds) {
        startDate = UF.toString(startDate);
        endDate = UF.toString(endDate);
        if (StringUtils.isBlank(startDate) && StringUtils.isBlank(endDate)) {
            SimpleDateFormat dateFormat = new SimpleDateFormat(NORMAL_DATE_FORMAT);
            Calendar calendar = Calendar.getInstance();
            endDate = dateFormat.format(calendar.getTime());
            calendar.add(Calendar.DAY_OF_YEAR, -6);
            startDate = dateFormat.format(calendar.getTime());
        }
        if (StringUtils.isBlank(startDate) || StringUtils.isBlank(endDate)) {
            return new SerializeObjectError("22000025");
        }
        List<String> channels = null;
        if (channelIds != null && channelIds.length > 0) {
            channels = new ArrayList<String>();
            for (String channelId : channelIds) {
                channels.add(channelId);
            }
        }
        List<GiveOutFutureValueBean> data = couponMemberService.listTicketFutureValueStatistics(startDate, endDate, channels);
        if (data != null && data.size() > 0) {
            page.setTotal(data.size());
            if (page.getPageSize() > 0) {
                data = data.stream().skip((PaginationUtil.getPage(page.getPageNum())-1) * page.getPageSize()).limit(page.getPageSize()).collect(Collectors.toList());
            }
            return new SerializeObject<>(ResultType.NORMAL, new DataTable<GiveOutFutureValueBean>(page.getPageNum(), page.getPageSize(), page.getTotal(), data));
        } else {
            return new SerializeObject<>(ResultType.NORMAL, new DataTable<GiveOutFutureValueBean>(page.getPageNum(), page.getPageSize(), page.getTotal(), new ArrayList<GiveOutFutureValueBean>()));
        }
    }

    @GetMapping(value = "/future/export")
    public SerializeObject exportFutureFutrueList(@RequestHeader String accessToken, String startDate, String endDate, String[] channelIds) {
        startDate = UF.toString(startDate);
        endDate = UF.toString(endDate);
        if (StringUtils.isBlank(startDate) && StringUtils.isBlank(endDate)) {
            SimpleDateFormat dateFormat = new SimpleDateFormat(NORMAL_DATE_FORMAT);
            Calendar calendar = Calendar.getInstance();
            endDate = dateFormat.format(calendar.getTime());
            calendar.add(Calendar.DAY_OF_YEAR, -6);
            startDate = dateFormat.format(calendar.getTime());
        }
        if (StringUtils.isBlank(startDate) || StringUtils.isBlank(endDate)) {
            return new SerializeObjectError("22000025");
        }
        List<String> channels = null;
        if (channelIds != null && channelIds.length > 0) {
            channels = new ArrayList<String>();
            for (String channelId : channelIds) {
                channels.add(channelId);
            }
        }
        List<GiveOutFutureValueBean> data = couponMemberService.listTicketFutureValueStatistics(startDate, endDate, channels);
        List<Serializable> list = new LinkedList<Serializable>();
        for(GiveOutFutureValueBean bean: data) {
            list.add(bean);
        }
        String path = ExcelUtil.writeToExcel(list, 0, properties.getTemplateUrl(), properties.getAccessKey(), properties.getSecretKey(), properties.getBucket(), properties.getFileDomain());
        if (StringUtils.isNotBlank(path)) {
            return new SerializeObject<>(ResultType.NORMAL, "", path);
        } else {
            return new SerializeObjectError("00000005");
        }
    }

    @GetMapping(value = "/avg/export")
    public SerializeObject exportAvgList(@RequestHeader String accessToken, Integer type, Integer timeType, String startDate, String endDate, String[] channelIds) {
        timeType = timeType == null ? 1 : timeType;
        type = type == null ? 1 : type;
        startDate = UF.toString(startDate);
        endDate = UF.toString(endDate);
        if (StringUtils.isBlank(startDate) && StringUtils.isBlank(endDate)) {
            SimpleDateFormat dateFormat = new SimpleDateFormat(NORMAL_DATE_FORMAT);
            if (timeType == 1) {
                Calendar calendar = Calendar.getInstance();
                endDate = dateFormat.format(calendar.getTime());
                calendar.add(Calendar.DAY_OF_YEAR, -6);
                startDate = dateFormat.format(calendar.getTime());
            } else if (timeType == 2) {
                Calendar calendar = Calendar.getInstance();
                endDate = dateFormat.format(calendar.getTime());
                calendar.add(Calendar.MONTH, -1);
                calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMinimum(Calendar.DAY_OF_MONTH));
                startDate = dateFormat.format(calendar.getTime());
            } else if (timeType == 3) {
                Calendar calendar = Calendar.getInstance();
                endDate = dateFormat.format(calendar.getTime());
                int week = calendar.get(Calendar.DAY_OF_WEEK);
                int days = 42;
                week--;
                if (week == 0) {
                    week = 7;
                }
                week--;
                days += week;
                calendar.add(Calendar.DAY_OF_YEAR, -days);
                startDate = dateFormat.format(calendar.getTime());
            }
        }
        if (StringUtils.isBlank(startDate) || StringUtils.isBlank(endDate)) {
            return new SerializeObjectError("22000025");
        }
        List<String> channels = null;
        if (channelIds != null && channelIds.length > 0) {
            channels = new ArrayList<String>();
            for (String channelId : channelIds) {
                channels.add(channelId);
            }
        }
        List<GiveOutAverageValueBean> data = couponMemberService.listAvgValueStatistics(type, timeType,startDate, endDate, channels);
        List<Serializable> list = new LinkedList<Serializable>();
        for(GiveOutAverageValueBean bean: data) {
            list.add(bean);
        }
        String path = ExcelUtil.writeToExcel(list, type, properties.getTemplateUrl(), properties.getAccessKey(), properties.getSecretKey(), properties.getBucket(), properties.getFileDomain());
        if (StringUtils.isNotBlank(path)) {
            return new SerializeObject<>(ResultType.NORMAL, "", path);
        } else {
            return new SerializeObjectError("00000005");
        }
    }

    @GetMapping(value = "/total/export")
    public SerializeObject exportList(@RequestHeader String accessToken, Page page, Integer timeType, String startDate, String endDate, String[] channelIds) {
        timeType = timeType == null ? 1 : timeType;
        startDate = UF.toString(startDate);
        endDate = UF.toString(endDate);
        if (StringUtils.isBlank(startDate) && StringUtils.isBlank(endDate)) {
            SimpleDateFormat dateFormat = new SimpleDateFormat(NORMAL_DATE_FORMAT);
            if (timeType == 1) {
                Calendar calendar = Calendar.getInstance();
                endDate = dateFormat.format(calendar.getTime());
                calendar.add(Calendar.DAY_OF_YEAR, -6);
                startDate = dateFormat.format(calendar.getTime());
            } else if (timeType == 2) {
                Calendar calendar = Calendar.getInstance();
                endDate = dateFormat.format(calendar.getTime());
                calendar.add(Calendar.MONTH, -1);
                calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMinimum(Calendar.DAY_OF_MONTH));
                startDate = dateFormat.format(calendar.getTime());
            } else if (timeType == 3) {
                Calendar calendar = Calendar.getInstance();
                endDate = dateFormat.format(calendar.getTime());
                int week = calendar.get(Calendar.DAY_OF_WEEK);
                int days = 42;
                week--;
                if (week == 0) {
                    week = 7;
                }
                week--;
                days += week;
                calendar.add(Calendar.DAY_OF_YEAR, -days);
                startDate = dateFormat.format(calendar.getTime());
            }
        }
        if (StringUtils.isBlank(startDate) || StringUtils.isBlank(endDate)) {
            return new SerializeObjectError("22000025");
        }
        List<String> channels = null;
        if (channelIds != null && channelIds.length > 0) {
            channels = new ArrayList<String>();
            for (String channelId : channelIds) {
                channels.add(channelId);
            }
        }
        List<GiveOutBean> data = couponMemberService.listGrantStatistics(timeType,startDate, endDate, channels);
        List<Serializable> list = new LinkedList<Serializable>();
        for(GiveOutBean bean: data) {
            list.add(bean);
        }
        String path = ExcelUtil.writeToExcel(list, 0, properties.getTemplateUrl(), properties.getAccessKey(), properties.getSecretKey(), properties.getBucket(), properties.getFileDomain());
        if (StringUtils.isNotBlank(path)) {
            return new SerializeObject<>(ResultType.NORMAL, "", path);
        } else {
            return new SerializeObjectError("00000005");
        }
    }
}
